package response

import (
	"net/http"
	"yunj/pkg/yunj/util"

	"github.com/flosch/pongo2/v6"
	"github.com/gin-gonic/gin"
)

// 上下文中需要渲染到html的数据key
const CTX_RENDER_HTML_DATA_KEY = "ctxRenderHtmlData"

// 上下文中需要渲染到html的数据
func CtxRenderHtmlData(ctx *gin.Context) (data map[string]any) {
	ctxRenderDataValue, ctxRenderDataExists := ctx.Get(CTX_RENDER_HTML_DATA_KEY)
	if !ctxRenderDataExists {
		return
	}
	ctxRenderData, ok := ctxRenderDataValue.(map[string]any)
	if !ok {
		return
	}
	data = ctxRenderData
	return
}

// 获取上下文中需要渲染到html的数据
func GetCtxRenderHtmlData[T any](ctx *gin.Context, key string) (value T, exists bool) {
	ctxRenderData := CtxRenderHtmlData(ctx)
	rawValue, exists := ctxRenderData[key]
	if !exists {
		return
	}
	_value, ok := rawValue.(T)
	if !ok {
		return
	}
	value = _value
	return
}

// 设置上下文中需要渲染到html的数据
func SetCtxRenderHtmlData(ctx *gin.Context, key string, value any) {
	ctxRenderData := CtxRenderHtmlData(ctx)
	if ctxRenderData == nil {
		ctxRenderData = map[string]any{}
	}
	ctxRenderData[key] = value
	ctx.Set(CTX_RENDER_HTML_DATA_KEY, ctxRenderData)
}

// 上下文中需要渲染到html的layModuleExtends数据key
const CTX_RENDER_HTML_DATA_LAY_MODULE_EXTENDS_KEY = "layModuleExtends"

// 设置上下文中需要渲染到html的layui扩展
func SetCtxRenderLayModuleExtend(ctx *gin.Context, name string, js string) {
	if name == "" || js == "" {
		return
	}
	layModuleExtends, exists := GetCtxRenderHtmlData[map[string]string](ctx, CTX_RENDER_HTML_DATA_LAY_MODULE_EXTENDS_KEY)
	if exists {
		layModuleExtends[name] = js
	} else {
		layModuleExtends = map[string]string{name: js}
	}
	SetCtxRenderHtmlData(ctx, CTX_RENDER_HTML_DATA_LAY_MODULE_EXTENDS_KEY, layModuleExtends)
}

// 设置上下文中需要渲染到html的layui扩展
func SetCtxRenderLayModuleExtends(ctx *gin.Context, layModuleExtends map[string]string) {
	if len(layModuleExtends) == 0 {
		return
	}
	var ctxLayModuleExtends map[string]string
	if currCtxLayModuleExtends, exists := GetCtxRenderHtmlData[map[string]string](ctx, CTX_RENDER_HTML_DATA_LAY_MODULE_EXTENDS_KEY); exists {
		ctxLayModuleExtends = util.MapMerge(currCtxLayModuleExtends, layModuleExtends)
	} else {
		ctxLayModuleExtends = layModuleExtends
	}
	SetCtxRenderHtmlData(ctx, CTX_RENDER_HTML_DATA_LAY_MODULE_EXTENDS_KEY, ctxLayModuleExtends)
}

// 设置上下文中需要渲染到html的js文件列表
func SetCtxRenderScriptFileList(ctx *gin.Context, scriptFileList []string) {
	ctxScriptFileList := []string{}
	if currCtxScriptFileList, exists := GetCtxRenderHtmlData[[]string](ctx, "scriptFileList"); exists {
		ctxScriptFileList = currCtxScriptFileList
	}
	ctxScriptFileList = append(ctxScriptFileList, scriptFileList...)
	ctxScriptFileList = util.SliceUnique(ctxScriptFileList) // 去重
	SetCtxRenderHtmlData(ctx, "scriptFileList", ctxScriptFileList)
}

// 渲染html页面
// @Param path string	模板文件路径
func RenderHtml(ctx *gin.Context, path string, data map[string]any) {
	if data == nil {
		data = map[string]any{}
	}
	// 设置上下文中需要渲染到html的数据
	ctxRenderHtmlData := CtxRenderHtmlData(ctx)
	for k, v := range ctxRenderHtmlData {
		data[k] = v
	}
	// 将gin.Context对象传递给模板
	data["ginContext"] = ctx
	// fmt.Println("模板渲染输出参数", data)
	ctx.HTML(http.StatusOK, path, pongo2.Context{
		"data": data,
	})
}

// 渲染html页面
// @Param path string	模板文件路径
func Render(ctx *gin.Context, path string, data map[string]any) {
	fullPath := path + ".html"
	RenderHtml(ctx, fullPath, data)
}
